package com.stars.home.activity

import android.os.Bundle
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.view.View
import android.widget.*
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.baidu.mapapi.map.*
import com.baidu.mapapi.model.LatLng
import com.baidu.mapapi.model.LatLngBounds
import com.baidu.mapapi.search.core.PoiInfo
import com.baidu.mapapi.search.core.SearchResult
import com.baidu.mapapi.search.poi.*
import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener
import com.baidu.mapapi.search.sug.SuggestionResult
import com.baidu.mapapi.search.sug.SuggestionResult.SuggestionInfo
import com.baidu.mapapi.search.sug.SuggestionSearch
import com.baidu.mapapi.search.sug.SuggestionSearchOption
import com.stars.home.R
import com.stars.home.adapter.baidu.SrarchPoiItemAdapter
import com.stars.home.base.MBActivity
import com.stars.home.databinding.ActivityBaiduSerachBinding
import com.stars.home.utils.baidu.Utils
import com.stars.home.vmodel.SearchBaiDuVModel

/**
 *on 2022/9/22
 */
class SearchBaiDuActivity: MBActivity<SearchBaiDuVModel, ActivityBaiduSerachBinding>(),
    BaiduMap.OnMapClickListener, BaiduMap.OnMarkerClickListener, OnGetPoiSearchResultListener,
    OnGetSuggestionResultListener{
    // 地图View实例
    private var mMapView: MapView? = null

    private var mBaiduMap: BaiduMap? = null

    private var mEditTextCity: EditText? = null

    private var mEditTextPoi: EditText? = null

    private var mPoiSearch: PoiSearch? = null

    private var mSuggestionSearch: SuggestionSearch? = null

    private var mRecyclerView: RecyclerView? = null

    private var mPoiTitle: TextView? = null

    private var mPoiAddress: TextView? = null
    var mLayoutDetailInfo:LinearLayout?=null


    private var mPoiItemAdaper: SrarchPoiItemAdapter? = null

    private var mBitmapDescWaterDrop = BitmapDescriptorFactory.fromResource(R.drawable.icon_binding_point)

    private var mBtnSearch: Button? = null

    private var mMarkerPoiInfo = HashMap<Marker, PoiInfo>()

    private var mPreSelectMarker: Marker? = null



    // 分页
    private var mLoadIndex = 0

    override fun init(savedInstanceState: Bundle?) {
        super.init(savedInstanceState)
        initView()

        initMap()

        mPoiSearch = PoiSearch.newInstance()
        mPoiSearch?.setOnGetPoiSearchResultListener(this)

        mSuggestionSearch = SuggestionSearch.newInstance()
        mSuggestionSearch?.setOnGetSuggestionResultListener(this)
    }

    private fun initMap() {
        if (null == mMapView) {
            return
        }
        mBaiduMap = mMapView!!.map
        if (null == mBaiduMap) {
            return
        }

        // 解决圆角屏幕手机，地图logo被遮挡的问题
        mBaiduMap!!.setViewPadding(30, 0, 30, 20)
        mMapView!!.showZoomControls(false)

        // 设置初始中心点为北京
        val center = LatLng(39.963175, 116.400244)
        val mapStatusUpdate = MapStatusUpdateFactory.newLatLngZoom(center, 12f)
        mBaiduMap!!.setMapStatus(mapStatusUpdate)
        mBaiduMap!!.setOnMapClickListener(this)
        mBaiduMap!!.setOnMarkerClickListener(this)
    }


    private fun initView() {
        mMapView = binding.mapview
        mEditTextCity =binding.city
        mEditTextPoi =binding.poi
        mBtnSearch = binding.btnSearch
        if (null == mEditTextCity || null == mEditTextPoi || null == mBtnSearch) {
            return
        }
        mEditTextPoi!!.setOnEditorActionListener { v, actionId, event -> false }

        mEditTextPoi?.addTextChangedListener(object:TextWatcher{
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                if (s?.isEmpty() == true && View.VISIBLE == mRecyclerView?.visibility) {
                    mRecyclerView?.visibility = View.INVISIBLE
                }
            }

            override fun afterTextChanged(s: Editable?) {
                // 获取检索城市
                val cityStr: String = mEditTextCity?.text.toString()
                // 获取检索关键字
                val keyWordStr: String = mEditTextPoi?.text.toString()
                if (TextUtils.isEmpty(cityStr) || TextUtils.isEmpty(keyWordStr)) {
                    return
                }
                if (View.VISIBLE == mRecyclerView?.visibility) {
                    mRecyclerView?.visibility = View.INVISIBLE
                }
                mSuggestionSearch?.requestSuggestion(
                    SuggestionSearchOption()
                        .city(cityStr)
                        .keyword(keyWordStr)
                        .citylimit(true)
                )
            }
        })
        mBtnSearch!!.setOnClickListener { searchPoiInCity() }
        mRecyclerView = binding.poiList
        val linearLayoutManager = LinearLayoutManager(this)
        if (null == mRecyclerView) {
            return
        }
        mRecyclerView!!.layoutManager = linearLayoutManager
        mPoiItemAdaper = SrarchPoiItemAdapter()
        mPoiItemAdaper?.setOnItemClickListener(AdapterView.OnItemClickListener { parent, view, position, id ->
            val suggestInfo: SuggestionInfo = mPoiItemAdaper?.getItemSuggestInfo(position)!!
            locateSuggestPoi(suggestInfo)
            setPoiTextWithLocateSuggestInfo(suggestInfo)
        })
        mRecyclerView!!.adapter = mPoiItemAdaper
        mRecyclerView!!.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                Utils.hideKeyBoard(this@SearchBaiDuActivity)
            }
        })
        mLayoutDetailInfo = binding.llPoint
        if (null == mLayoutDetailInfo) {
            return
        }
        mPoiTitle = binding.poiTitle
        mPoiAddress = binding.poiAddress
    }

    private fun searchPoiInCity() {
        val cityStr = mEditTextCity!!.text.toString()
        // 获取检索关键字
        val keyWordStr = mEditTextPoi!!.text.toString()
        if (TextUtils.isEmpty(cityStr) || TextUtils.isEmpty(keyWordStr)) {
            return
        }
        if (View.VISIBLE == mRecyclerView!!.visibility) {
            mRecyclerView!!.visibility = View.INVISIBLE
        }
        mPoiSearch!!.searchInCity(
            PoiCitySearchOption()
                .city(cityStr)
                .keyword(keyWordStr)
                .pageNum(mLoadIndex) // 分页编号
                .cityLimit(true)
                .scope(1)
        )
    }

    /**
     * 在地图上定位poi
     *
     * @param suggestInfo
     */
    private fun locateSuggestPoi(suggestInfo: SuggestionInfo?) {
        if (null == suggestInfo) {
            return
        }
        if (null == mRecyclerView || null == mMapView) {
            return
        }
        mRecyclerView!!.visibility = View.INVISIBLE
        val latLng = suggestInfo.getPt()

        // 将地图平移到 latLng 位置
        val mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latLng)
        mBaiduMap!!.setMapStatus(mapStatusUpdate)

        // 隐藏输入法
        Utils.hideKeyBoard(this)

        // 清除之前的
        clearData()

        // 显示当前的
        if (showSuggestMarker(latLng)) {
            showPoiInfoLayout(suggestInfo)
        } else {
            setPoiTextWithLocateSuggestInfo(suggestInfo)
            searchPoiInCity()
        }
    }

    /**
     * 选中某条sug检索结果时，将mEditPoi的文字设置为该sug检索结果的key
     *
     * @param suggestInfo
     */
    private fun setPoiTextWithLocateSuggestInfo(suggestInfo: SuggestionInfo?) {
        if (null == suggestInfo) {
            return
        }
//        mEditTextPoi!!.removeTextChangedListener(mMyTextWatcher) // 暂时移除调TextWatcher，防止触发sug检索
        mEditTextPoi!!.setText(suggestInfo.getKey())
        mEditTextPoi!!.setSelection(suggestInfo.getKey().length) // 将光标移到末尾
//        mEditTextPoi!!.addTextChangedListener(mMyTextWatcher)
    }


    private fun setPoiResult(poiInfos: List<PoiInfo>?) {
        if (null == poiInfos || poiInfos.size <= 0) {
            return
        }
        clearData()

        // 将地图平移到 latLng 位置
        val latLng = poiInfos[0].getLocation()
        val mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latLng)
        mBaiduMap!!.setMapStatus(mapStatusUpdate)
        val itr: Iterator<*> = poiInfos.iterator()
        val latLngs: MutableList<LatLng> = ArrayList()
        var poiInfo: PoiInfo? = null
        var i = 0
        while (itr.hasNext()) {
            poiInfo = itr.next() as PoiInfo?
            if (null == poiInfo) {
                continue
            }
            locatePoiInfo(poiInfo, i)
            latLngs.add(poiInfo.getLocation())
            if (0 == i) {
                showPoiInfoLayout(poiInfo)
            }
            i++
        }
        setBounds(latLngs)
    }

    private fun clearData() {
        mBaiduMap!!.clear()
        mMarkerPoiInfo.clear()
        mPreSelectMarker = null
    }

    private fun locatePoiInfo(poiInfo: PoiInfo?, i: Int) {
        if (null == poiInfo) {
            return
        }

        // 隐藏输入法
        Utils.hideKeyBoard(this)

        // 显示当前的
        showPoiMarker(poiInfo, i)
    }

    private fun showPoiMarker(poiInfo: PoiInfo?, i: Int) {
        if (null == poiInfo) {
            return
        }
        val markerOptions = MarkerOptions()
            .position(poiInfo.getLocation())
            .icon(mBitmapDescWaterDrop)

        // 第一个poi放大显示
        if (0 == i) {
            val infoWindow = getPoiInfoWindow(poiInfo)
            markerOptions.scaleX(1.5f).scaleY(1.5f).infoWindow(infoWindow)
        }
        val marker = mBaiduMap!!.addOverlay(markerOptions) as Marker
        if (null != marker) {
            mMarkerPoiInfo[marker] = poiInfo
            if (0 == i) {
                mPreSelectMarker = marker
            }
        }
    }

    private fun getPoiInfoWindow(poiInfo: PoiInfo): InfoWindow {
        val textView = TextView(this)
        textView.text = poiInfo.getName()
        textView.setPadding(10, 5, 10, 5)
        textView.background = this.resources.getDrawable(R.drawable.bg_info)
        return InfoWindow(textView, poiInfo.getLocation(), -150)
    }

    /**
     * 显示定位点
     *
     * @param latLng
     */
    private fun showSuggestMarker(latLng: LatLng?): Boolean {
        if (null == latLng) {
            return false
        }
        val markerOptions = MarkerOptions()
            .position(latLng)
            .icon(mBitmapDescWaterDrop)
            .scaleX(1.5f)
            .scaleY(1.5f)
        mBaiduMap!!.addOverlay(markerOptions)
        return true
    }

    /**
     * 显示底部suggestion详情
     *
     * @param suggestInfo
     */
    private fun showPoiInfoLayout(suggestInfo: SuggestionInfo?) {
        if (null == mLayoutDetailInfo || null == suggestInfo) {
            return
        }
        if (null == mPoiTitle) {
            return
        }
        if (null == mPoiAddress) {
            return
        }
        mLayoutDetailInfo!!.visibility = View.VISIBLE
        mPoiTitle!!.text = suggestInfo.getKey()
        val address = suggestInfo.getAddress()
        if (TextUtils.isEmpty(address)) {
            mPoiAddress!!.visibility = View.GONE
        } else {
            mPoiAddress!!.text = suggestInfo.getAddress()
            mPoiAddress!!.visibility = View.VISIBLE
        }
    }

    /**
     * 显示底部poi详情
     *
     * @param poiInfo
     */
    private fun showPoiInfoLayout(poiInfo: PoiInfo?) {
        if (null == mLayoutDetailInfo || null == poiInfo) {
            return
        }
        if (null == mPoiTitle) {
            return
        }
        if (null == mPoiAddress) {
            return
        }
        mLayoutDetailInfo!!.visibility = View.VISIBLE
        mPoiTitle!!.text = poiInfo.getName()
        val address = poiInfo.getAddress()
        if (TextUtils.isEmpty(address)) {
            mPoiAddress!!.visibility = View.GONE
        } else {
            mPoiAddress!!.text = poiInfo.getAddress()
            mPoiAddress!!.visibility = View.VISIBLE
        }
    }

    /**
     * 隐藏详情
     */
    private fun hideInfoLayout() {
        if (null == mLayoutDetailInfo) {
            return
        }
        mLayoutDetailInfo!!.visibility = View.GONE
    }

    /**
     * 最佳视野内显示所有点标记
     */
    private fun setBounds(latLngs: List<LatLng>?) {
        if (null == latLngs || latLngs.size <= 0) {
            return
        }
        val horizontalPadding = 80
        val verticalPaddingBottom = 400

        // 构造地理范围对象
        val builder = LatLngBounds.Builder()
        // 让该地理范围包含一组地理位置坐标
        builder.include(latLngs)

        // 设置显示在指定相对于MapView的padding中的地图地理范围
        val mapStatusUpdate = MapStatusUpdateFactory.newLatLngBounds(
            builder.build(),
            horizontalPadding,
            verticalPaddingBottom,
            horizontalPadding,
            verticalPaddingBottom
        )
        // 更新地图
        mBaiduMap!!.setMapStatus(mapStatusUpdate)
        // 设置地图上控件与地图边界的距离，包含比例尺、缩放控件、logo、指南针的位置
        mBaiduMap!!.setViewPadding(
            0,
            0,
            0,
            verticalPaddingBottom
        )
    }


    override fun vmClass(): Class<SearchBaiDuVModel> {
        return SearchBaiDuVModel::class.java
    }
    override fun binding(): ActivityBaiduSerachBinding {
       return ActivityBaiduSerachBinding.inflate(layoutInflater)
    }

    override fun title(): String? {
        return null
    }


    override fun onMapClick(p0: LatLng?) {
        Utils.hideKeyBoard(this)
    }

    override fun onMapPoiClick(p0: MapPoi?) {
    }

    override fun onMarkerClick(marker: Marker?): Boolean {
        if (null == marker || null == mMarkerPoiInfo || mMarkerPoiInfo.size <= 0) {
            return false
        }

        val itr: Iterator<*> = mMarkerPoiInfo.entries.iterator()
        var tmpMarker: Marker
        var poiInfo: PoiInfo? = null
        var markerPoiInfoEntry: Map.Entry<Marker?, PoiInfo?>
        while (itr.hasNext()) {
            markerPoiInfoEntry = itr.next() as Map.Entry<Marker?, PoiInfo?>
            tmpMarker = markerPoiInfoEntry?.key!!
            if (null == tmpMarker) {
                continue
            }
            if (tmpMarker.id === marker.getId()) {
                poiInfo = markerPoiInfoEntry.value
                break
            }
        }

        if (null == poiInfo) {
            return false
        }

        val infoWindow = getPoiInfoWindow(poiInfo)

        mBaiduMap!!.showInfoWindow(infoWindow)

        showPoiInfoLayout(poiInfo)

        if (null != mPreSelectMarker) {
            mPreSelectMarker!!.scale = 1.0f
        }

        marker.setScale(1.5f)
        mPreSelectMarker = marker

        return true
    }

    override fun onGetPoiResult(poiResult: PoiResult?) {
        if (poiResult == null || poiResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
            mLoadIndex = 0
            Toast.makeText(this@SearchBaiDuActivity, "未找到结果", Toast.LENGTH_LONG).show()
            return
        }

        val poiInfos: List<PoiInfo> = poiResult.allPoi
            ?: return

        mRecyclerView!!.visibility = View.GONE

        setPoiResult(poiInfos)
    }

    override fun onGetPoiDetailResult(p0: PoiDetailResult?) {
    }

    override fun onGetPoiDetailResult(p0: PoiDetailSearchResult?) {
    }

    override fun onGetPoiIndoorResult(p0: PoiIndoorResult?) {
    }

    override fun onGetSuggestionResult(suggestionResult: SuggestionResult?) {
        if (suggestionResult == null
            || suggestionResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND
        ) {
            mLoadIndex = 0
            Toast.makeText(this@SearchBaiDuActivity, "未找到结果", Toast.LENGTH_LONG).show()
            return
        }

        val suggesInfos: List<SuggestionInfo> = suggestionResult.allSuggestions
            ?: return

        // 隐藏之前的

        // 隐藏之前的
        hideInfoLayout()

        mRecyclerView!!.visibility = View.VISIBLE

        if (null == mPoiItemAdaper) {
            mPoiItemAdaper = SrarchPoiItemAdapter(suggesInfos)
        } else {
            mPoiItemAdaper!!.updateData(suggesInfos)
        }
    }

}
